/**********************************************************************/
#include <QtCore/QCoreApplication>

/**********************************************************************/
#include <iostream>
#include <signal.h>

/**********************************************************************/
#include "server.h"
#include "chatserver.h"
#include "controlserver.h"

/**********************************************************************/
using namespace std;

/**********************************************************************/
void sigint(int code);
void printUsage(char *cmd);
void parseArgs(int argc, char *argv[]);

/**********************************************************************/
quint16 serverPort = DEFAULT_SERVER_PORT;
quint16 controlPort = DEFAULT_CONTROL_PORT;
bool silent = DEFAULT_SILENT;
QCoreApplication *ap;
ChatServer *sp;

/**********************************************************************/
int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  ChatServer s;
  ControlServer c;

  ap = &a;
  sp = &s;

  signal(SIGINT, sigint);

  if(argc > 1)
    parseArgs(argc, argv);

  if(!silent)
  {
    s.connect(&s, SIGNAL(logMessage(QString)),
                       &s, SLOT(printLogMessage(QString)));
    c.connect(&c, SIGNAL(logMessage(QString)),
                          &c, SLOT(printLogMessage(QString)));
  }

  s.connect(&s, SIGNAL(error(QString)),
                     &s, SLOT(printLogMessage(QString)));
  c.connect(&c, SIGNAL(error(QString)),
                        &c, SLOT(printLogMessage(QString)));

  a.connect(&a, SIGNAL(aboutToQuit()), &s, SLOT(quit()));
  a.connect(&a, SIGNAL(aboutToQuit()), &c, SLOT(quit()));

  s.start(serverPort);
  c.start(controlPort);

  return a.exec();
}

/**********************************************************************/
void parseArgs(int argc, char *argv[])
{
  int parseComplete = 0;

  for(int i = 1; i < argc; i++)
  {
    if(strstr(argv[i], "-h") != NULL ||
       strstr(argv[i], "--help") != NULL)
    {
      printUsage(argv[0]);
      exit(EXIT_SUCCESS);
    }

    if((strstr(argv[i], "-p") != NULL ||
        strstr(argv[i], "--port") != NULL))
    {
      if((atoi(argv[i + 1]) > 1024 && atoi(argv[i + 1]) < 65535))
      {
        serverPort = (quint16) atoi(argv[i + 1]);
        parseComplete += 2;
      }
      else
      {
        printUsage(argv[0]);
        exit(EXIT_SUCCESS);
      }
    }

    if((strstr(argv[i], "-c") != NULL ||
        strstr(argv[i], "--control-port") != NULL))
    {
      if((atoi(argv[i + 1]) > 1024 && atoi(argv[i + 1]) < 65535) &&
         (atoi(argv[i + 1]) != serverPort))
      {
        controlPort = (quint16) atoi(argv[i + 1]);
        parseComplete += 2;
      }
      else
      {
        printUsage(argv[0]);
        exit(EXIT_SUCCESS);
      }
    }

    if(strstr(argv[i], "-s") != NULL ||
       strstr(argv[i], "--silent") != NULL)
    {
      silent = true;
      parseComplete++;
    }
  }

  if(parseComplete < argc - 1)
  {
    printUsage(argv[0]);
    exit(EXIT_SUCCESS);
  }
}

/**********************************************************************/
void printUsage(char *cmd)
{
  cout << QString(HELP_TEXT).arg(cmd).toStdString() << endl;
}

/**********************************************************************/
void sigint(int code)
{
  if(code == SIGINT)
  {
    sp->stop();
    ap->quit();
    exit(EXIT_SUCCESS);
  }
}
